121. 买卖股票的最佳时机
121. 买卖股票的最佳时机
Similar Question
Solution Tips
方案一: 暴力法
public class Solution {
public int maxProfit(int[] prices) {
int maxprofit = 0;
for (int i = 0; i < prices.length - 1; i++) {
for (int j = i + 1; j < prices.length; j++) {
int profit = prices[j] - prices[i];
if (profit > maxprofit) {
maxprofit = profit;
}
}
}
return maxprofit;
}
}
方案二: 贪心
保留当前遍历到的最小值, 不断的获取与当前遍历到的值的差值.
遇到了新的最小值, 就直接切换成新的最小值即可. 因为再出现更大的值, 也是与最小值的差才是最大的
var maxProfit = function(prices) {
let lowerPrice = prices[0];// 重点是维护这个最小值(贪心的思想)
let profit = 0;
for(let i = 0; i < prices.length; i++){
lowerPrice = Math.min(lowerPrice, prices[i]);// 贪心地选择左面的最小价格
profit = Math.max(profit, prices[i] - lowerPrice);// 遍历一趟就可以获得最大利润
}
return profit;
};
对方法二的另一种解释: 方法二可以看做一种动态规划,只不过对空间复杂度进行了优化。考虑每次如何获取最大收益?第 i 天的最大收益只需要知道前 i 天的最低点就可以算出来了。而第 i 天以前(包括第 i 天)的最低点和 i-1 天的最低点有关,至此我们的动态方程就出来了。
dp[i] = min(dp[i-1], prices[i])
其中 dp[0]=prices[0]
,然后动态计算之后的就可以了。 得到了前 i 天的最低点以后,只需要维护一个 max 用来保存最大收益就可以了。 这个时候是空间复杂度 O(n)的动态规划,代码如下:
//dp[i]表示截止到i,价格的最低点是多少 dp[i]=min(dp[i-1],nums[i])
int max = 0;
int[] dp = new int[prices.length];
dp[0] = prices[0];
for (int i = 1; i < prices.length; i++) {
dp[i] = (dp[i - 1] < prices[i]) ? dp[i - 1] : prices[i];
max = (prices[i] - dp[i]) > max ? prices[i] - dp[i] : max;
}
return max;
接着考虑优化空间,仔细观察动态规划的辅助数组,其每一次只用到了 dp[-1] 这一个空间,因此可以把数组改成单个变量 dp 来存储截止到第 i 天的价格最低点。优化之后的代码就是题解中的方法二。
方案三: 动态规划
放弃, 迷惑的不行